package com.gitee.wsl.mathematics.interpolator

import kotlin.math.absoluteValue

sealed interface PercentOrRatio:Comparable<PercentOrRatio>{

    val value:Double

    fun isNaN(): Boolean = value.isNaN()

    fun toDouble(): Double = value
    fun toFloat(): Float = value.toFloat()

    val absoluteValue  get() = create(value.absoluteValue)

    fun create(value: Double): PercentOrRatio

    operator fun plus(other: PercentOrRatio)  = create(value + other.value)
    operator fun minus(other: PercentOrRatio) = create(value - other.value)
    operator fun times(other: PercentOrRatio)  = create(value * other.value)
    operator fun div(d: Number)             = create(value / d.toDouble())

    /**
     * Operator to allow to write `20.pct * 3` (= 0.6)
     */
    operator fun times(d: Number):Double = value * d.toDouble()
    operator fun unaryMinus()         = create(-value)
    operator fun unaryPlus()          = create(+value)
    override operator fun compareTo(other: PercentOrRatio)   : Int = this.value.compareTo(other.value)

    /**
     * if > 100% returns 100%,
     * if < 0% returns 0%,
     * else return the current value.
     */
    fun coerceToDefault() = create(value.coerceIn(.0, 1.0))
}

/**
 * Extension operator to allow to write `3 * 20.pct` (= 0.6)
 */
operator fun Int.times(percent: PercentOrRatio) =  this * percent.value

operator fun Float.times(percent: PercentOrRatio) =  this * percent.value

operator fun Double.times(percent: PercentOrRatio) = this * percent.value

operator fun Long.times(percent: PercentOrRatio) =  this * percent.value